package hard;

import sword.offer.common.GenerateTree;
import sword.offer.common.TreeNode;

import java.util.Arrays;
import java.util.Objects;
import java.util.StringJoiner;

/**
 * @author 胡宇轩
 * @Email: programboy@163.com
 */
public class SerializeAndDeserializeBinaryTree {
    public static void main(String[] args) {
        TreeNode treeNode = GenerateTree.generateTree1(Arrays.asList(1,2,3,null,null,4,5));
        Codec codec = new Codec();
        String serialize = codec.serialize(treeNode);
        System.out.println(serialize);
        codec.deserialize(serialize);
        System.out.println("");
    }

    public static class Codec {
        StringJoiner joiner = new StringJoiner(",");
        int index = 0;
        // Encodes a tree to a single string.
        public String serialize(TreeNode root) {
            executeSerialize(root);
            return joiner.toString();
        }

        private void executeSerialize(TreeNode root) {
            if (Objects.isNull(root)) {
                joiner.add("#");
                return;
            }
            joiner.add(String.valueOf(root.val));
            executeSerialize(root.left);
            executeSerialize(root.right);
        }

        // Decodes your encoded data to tree.
        public TreeNode deserialize(String data) {
            String[] nodes = data.split(",");
            return recurBuildTree(nodes);
        }

        private TreeNode recurBuildTree(String[] nodes) {
            if ("#".equals(nodes[index])) {
                index++;
                return null;
            }
            TreeNode curNode = new TreeNode(Integer.parseInt(nodes[index++]));
            curNode.left = recurBuildTree(nodes);
            curNode.right = recurBuildTree(nodes);
            return curNode;
        }
    }
}
